package blackstar.performance.transform.matcher;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author RayWoo (ayufox@gmail.com)
 * 
 */
public class DefaultPointCutMatcher implements PointCutMatcher
{
	private List<String> includePackages = new ArrayList<String>();
	private List<String> excludePackages = new ArrayList<String>();
	private List<String> includeClassNameRegExps = new ArrayList<String>();
	private List<String> excludeClassNameRegExps = new ArrayList<String>();
	private List<String> includeMethodRegExps = new ArrayList<String>();
	private List<String> excludeMethodRegExps = new ArrayList<String>();

	public void addIncludePackage(String pkg)
	{
		this.includePackages.add(pkg);
	}

	public void addExcludePackage(String pkg)
	{
		this.excludePackages.add(pkg);
	}

	public void addIncludeMethodRegExp(String regexp)
	{
		this.includeMethodRegExps.add(regexp);
	}

	public void addExcludeMethodRegExp(String regexp)
	{
		this.excludeMethodRegExps.add(regexp);
	}

	public void addIncludeClassRegExp(String regexp)
	{
		this.includeClassNameRegExps.add(regexp);
	}

	public void addExcludeClassRegExp(String regexp)
	{
		this.excludeClassNameRegExps.add(regexp);
	}


	public String matchPackage(String packageName)
	{
		// Exclude优先判断
		for (String pkg : this.excludePackages)
		{
			if (packageName.startsWith(pkg))
			{
				return null;
			}
		}

		// 没有include，默认所有
		if (includePackages.size() == 0)
		{
			return "";
		} else
		{
			for (String pkg : this.includePackages)
			{
				if (packageName.startsWith(pkg))
				{
					return pkg;
				}
			}

			return null;
		}
	}
	
	public boolean isClassMatch(String className)
	{
		for (String regexp : this.excludeClassNameRegExps)
		{
			if (isMatchRegExp(className, regexp))
			{
				return false;
			}
		}

		if (this.includeClassNameRegExps.size() == 0)
		{
			return true;
		} else
		{
			for (String regexp : this.includeClassNameRegExps)
			{
				if (isMatchRegExp(className, regexp))
				{
					return true;
				}
			}

			return false;
		}
	}

	public boolean isMethodMatch(String methodName)
	{
		for (String regexp : this.excludeMethodRegExps)
		{
			if (isMatchRegExp(methodName, regexp))
			{
				return false;
			}
		}

		if (this.includeMethodRegExps.size() == 0)
		{
			return true;
		} else
		{
			for (String regexp : this.includeMethodRegExps)
			{
				if (isMatchRegExp(methodName, regexp))
				{
					return true;
				}
			}

			return false;
		}
	}

	private boolean isMatchRegExp(String string, String regexp)
	{
		Pattern pattern = Pattern.compile(regexp);
		Matcher matcher = pattern.matcher(string);
		if (matcher.find())
		{
			return true;
		} else
		{
			return false;
		}
	}
}
